//
//    AppMixer.cpp
//    Class for managing mixers
//    2006 John Wiggins
//
// This program is free software; you can redistribute it and/or modify  
// it under the terms of the GNU General Public License as published by  
// the Free Software Foundation; either version 2 of the License, or     
// (at your option) any later version.                                   
// 
// This program is distributed in the hope that it will be useful,       
// but WITHOUT ANY WARRANTY; without even the implied warranty of        
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         
// GNU General Public License for more details.                          
//     
//     You should have received a copy of the GNU General Public License     
//     along with this program; if not, write to the                         
//         Free Software Foundation, Inc.,                                       
//         59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.  
//
//-------------------------------------------------------------
#include "AppMixer.h"
//-------------------------------------------------------------
AppMixer::AppMixer( ge_mixer_plugin *mixer )
: mMixerPlugin( mixer )
{
    // init the surface pool
    // with empty images
    //std::vector<RenSurface *> mSurfacePool;
    mSurfacePool.push_back( new RenSurface( GE_FMT_GRAY, 0, 0 ) );
    mSurfacePool.push_back( new RenSurface( GE_FMT_GRAY, 0, 0 ) );

    // "pointers" to the surfaces
    mWorkSurface = 0;
    mScratchSurface = 1;
}
//-------------------------------------------------------------
AppMixer::~AppMixer()
{
    // delete the surfaces in the pool
    delete mSurfacePool[0];
    delete mSurfacePool[1];
}
//-------------------------------------------------------------
void
AppMixer::mix( uint32 numSrcs, RenSurface **srcList )
{
    uint32 numFilters = mFiltList.size();

    // run the mixer
    mMixerPlugin->mix( mMixerPlugin, numSrcs, srcList,
                                        mSurfacePool[mWorkSurface] );
        
    // did the size or format change?
    if ( *mSurfacePool[mWorkSurface] != *mSurfacePool[mScratchSurface] )
    {
        // oh no! update the scratch surface to match the work surface
        mSurfacePool[mScratchSurface]->modifyAttributes( 
                        mSurfacePool[mWorkSurface]->colorFormat(),
                        mSurfacePool[mWorkSurface]->width(),
                        mSurfacePool[mWorkSurface]->height()
                                                        );
    }

    // run through the filters
    for ( uint32 i=0; i < numFilters; i++ )
    {
        mFiltList[i]->filter( mFiltList[i], mSurfacePool[mWorkSurface],
                                        mSurfacePool[mScratchSurface] );
        // swap work and scratch surfaces
        uint32 tmp = mWorkSurface;
        mWorkSurface = mScratchSurface;
        mScratchSurface = tmp;
    }
}
//-------------------------------------------------------------
void
AppMixer::addFilter( ge_filter_plugin *filt, ge_filter_plugin *before )
{
    // if 'before' is NULL, the filter goes at the end of the list
    if ( before == NULL )
    {
        mFiltList.push_back( filt );
    }
    else
    {
        // find plugin pointed to by 'before'
        for ( std::vector<ge_filter_plugin *>::iterator i = mFiltList.begin();
                    i != mFiltList.end(); ++i )
        {
            if ( *i == before )
            {
                // insert 'filt' before 'before'
                mFiltList.insert( i, filt );
                break;
            }
        }
    }
}
//-------------------------------------------------------------
void
AppMixer::removeFilter( ge_filter_plugin *filt )
{
    // find the filter pointed to by 'filt'
    for ( std::vector<ge_filter_plugin *>::iterator i = mFiltList.begin();
                i != mFiltList.end(); ++i )
    {
        // and remove it from the list
        if ( *i == filt )
        {
            mFiltList.erase( i );
            break;
        }
    }
}
//-------------------------------------------------------------
